/*
    创建者：shuxiaokai
    创建时间：2021-07-28 22:11
    模块名称：左右拖动组件
    备注：
*/
<template>
  <div ref="wrapper" :style="{'userSelect': isDragging ? 'none' : 'auto'}" class="drag-wrap-y">
    <div ref="bar" class="bar" :class="{active: isDragging}" @mousedown="handleResizeMousedown" @dblclick="handleReset"></div>
    <div v-if="isDragging" class="indicator">
      <div class="top"></div>
      <div class="ct">
        <div>{{ realTimeHeight }}px({{ $t("双击还原") }})</div>
        <!-- <div></div> -->
      </div>
      <div class="bottom"></div>
    </div>
    <slot />
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  props: {
    /**
         * 初始高度
         */
    height: {
      type: Number,
      default: null,
    },
    /**
         * 最小高度
         */
    min: {
      type: Number,
      default: 100,
    },
    /**
         * 最大高度
         */
    max: {
      type: Number,
      default: 400,
    },
    /**
         * 是否记忆上次位置信息
         */
    remember: {
      type: Boolean,
      default: true,
    },
    /**
         * 组件名称(必填，用于localstorage存储)
         */
    name: {
      type: String,
      required: true,
    },
  },
  emits: ['dragStart', 'dragEnd'],
  data() {
    return {
      realTimeHeight: 0, //---------------实时高度
      mousedownTop: 0, //---------------鼠标点击距离
      wrapperHeight: 0, //----------------拖拽dom元素高度
      isDragging: false, //--------------是否正在拖拽
    };
  },
  mounted() {
    this.initDrag();
  },
  unmounted() {
    document.documentElement.removeEventListener('mousemove', this.handleResizeMousemove);
    document.documentElement.removeEventListener('mouseup', this.handleResizeMouseup)
  },
  methods: {
    //初始化拖拽相关事件
    initDrag() {
      document.documentElement.addEventListener('mouseup', this.handleResizeMouseup);
      const { wrapper, bar } = this.$refs;
      const height = this.height ? `${this.height}px` : `${(this.$refs.wrapper as HTMLElement).getBoundingClientRect().height}px`;
      if (this.remember) {
        const wrapperHeight = localStorage.getItem(`dragBar/${this.name}`) || height;
        (bar as HTMLElement).style.top = '-3px';
        (wrapper as HTMLElement).style.height = `${wrapperHeight}`;
        this.realTimeHeight = parseFloat(wrapperHeight);
      } else {
        (bar as HTMLElement).style.top = '-3px';
        (wrapper as HTMLElement).style.height = height;
        this.realTimeHeight = parseFloat(height);
      }
    },
    //处理鼠标弹起事件
    handleResizeMouseup() {
      this.isDragging = false;
      document.documentElement.removeEventListener('mousemove', this.handleResizeMousemove);
      this.$emit('dragEnd');
    },
    //处理鼠标按下事件
    handleResizeMousedown(e: MouseEvent) {
      this.mousedownTop = e.clientY;
      this.wrapperHeight = (this.$refs.wrapper as HTMLElement).getBoundingClientRect().height;
      this.isDragging = true;
      document.documentElement.addEventListener('mousemove', this.handleResizeMousemove);
      this.$emit('dragStart')
    },
    //处理鼠标移动事件
    handleResizeMousemove(e: MouseEvent) {
      const { bar, wrapper } = this.$refs;
      let moveTop = 0;
      moveTop = this.mousedownTop - e.clientY;
      const wrapperHeight = moveTop + this.wrapperHeight;
      if (wrapperHeight < this.min || wrapperHeight > this.max) {
        return;
      }
      (bar as HTMLElement).style.top = '-3px';
      (wrapper as HTMLElement).style.height = `${moveTop + this.wrapperHeight}px`;
      if (this.remember) {
        localStorage.setItem(`dragBar/${this.name}`, `${moveTop + this.wrapperHeight}px`);
      }
      this.realTimeHeight = moveTop + this.wrapperHeight;
    },
    //还原高度
    handleReset() {
      const { bar, wrapper } = this.$refs;
      const height = this.height ? `${this.height}px` : `${(wrapper as HTMLElement).getBoundingClientRect().height}px`;
      (bar as HTMLElement).style.height = '-3px';
      (wrapper as HTMLElement).style.height = height;
      this.realTimeHeight = parseFloat(height);
      if (this.remember) {
        localStorage.setItem(`dragBar/${this.name}`, height);
      }
    },
  },
})
</script>

<style lang="scss">
.drag-wrap-y {
    position: relative;
    .indicator {
        width: 100%;
        position: absolute;
        top: 1px;
        z-index: 1;
        display: flex;
        align-items: center;
        padding: 0 size(10);
        .top, .bottom {
            border-bottom: 1px dashed $red;
            flex: 1;
        }
        .ct {
            width: size(150);
            flex: 0 0 auto;
            text-align: center;
            color: $gray-600;
        }
    }
    &>.bar {
        position: absolute;
        height: size(6);
        width: 100%;
        background: transparent;
        z-index: $zIndex-drag-bar;
        box-sizing: content-box;
        cursor: ns-resize;
        left: 0;
        &.active {
            background: $theme-color;
        }
    }
}
</style>
